#pragma once

#include "../ImageCores/xImage.h"

// CQuickFillCtrler command target

class CQuickFillCtrler : public CObject
{
public:
	CQuickFillCtrler(CxImage* pImage, COLORREF fillColor, COLORREF borderColor=CLR_INVALID);
	virtual ~CQuickFillCtrler();

	inline void SetImage(CxImage* pImage);
	inline CxImage* GetImage();
	inline void SetFillColor(COLORREF fillColor);
	inline COLORREF GetFillColor();

	/* Quick fill the given image from the point with fill color
	 * Arguments:
	 *		Pointer to bitmap to fill, point: coordinates of seed point,
	 *		color used for solid or masked fills, border color used if area to
	 *		be filled is outlined (or CLR_INVALID).
	 *
	 * Returns:
	 *		 0 = Success.
	 *		-1 = Invalid seed point.
	 *		-2 = Memory allocation error.
	 *		-3 = Invalid bitmap or unknown error.
	 */
	int QuickFill(CPoint point, COLORREF fillColor);
	int QuickFill(CPoint point);
private:

	typedef struct hlineNode_st {
		int x1, x2, y, dy;
		struct hlineNode_st *pNext,*pPrev;
	} HLINE_NODE;

	BOOL CreateFreeList();
	void FreeLists();
	void PushLine(int x1, int x2, int y, int dy);
	void PopLine(int &x1, int &x2, int &y, int &dy);
	void PopThis(HLINE_NODE *pThis);
	void PushVisitedLine(int x1, int x2, int y);
	void PushOpposite(int OldX1, int OldX2, int x1, int x2, int y, int dy);
	BOOL IsRevisit(int x1, int x2, int y);

	int ScanLeft(int x, int y, int xmin, DWORD dwValue);
	int ScanRight(int x, int y, int xmax, DWORD dwValue);
	int SearchLeft(int x, int y, int xmin, DWORD dwValue);
	int SearchRight(int x, int y, int xmax, DWORD dwValue);
	HLINE_NODE* FindNextLine(int x1, int x2, int y);

	HLINE_NODE*	m_pVisitList;
	HLINE_NODE*	m_pLineList;
	HLINE_NODE*	m_pFreeList;

	BOOL m_bXSortOn;
	BOOL m_bMemError;
	int m_LastY;

	COLORREF m_fillColor;
	COLORREF m_borderColor;
	CxImage* m_pImage;

	// Private information members
	RECT m_rcInvalid;

private:
#ifdef QUICKFILL_TEST
	unsigned m_CurStackSize;
	unsigned m_MaxStackSize;
	unsigned m_VisitSize;
	int m_CurrentLine;
	int m_Direction;
	int m_nRevisitCount;
	BOOL m_bShowRevisits;
#endif
#ifdef QUICKFILL_SLOW
	BOOL m_bSlowMode;
#endif
};